﻿
// 2022/7/8: 首个版本
// 2022/7/11: 新增getFFMPEGLibraryVersion
// 2022/7/11: 修正get_ffmpeg_interface_version符号加载
// 2022/7/11: 添加IFFMPEGInterfaceV101
// 2022/7/11: 宏改为常量
// 2022/7/12: 添加IFFMPEGInterfaceV102
// 2022/7/14: 添加IFFMPEGInterfaceV103
// 2022/7/19: 添加IFFMPEGInterfaceV104
// 2022/8/8: 添加IFFMPEGInterfaceV105
// 2022/9/1: 增加AVPixelFormat::AV_PIX_FMT_YUV422P/AV_PIX_FMT_YUVJ422P
// 2022/9/30: 增加getUsingFFMPEGDLVersion
// 2023/7/12: 添加IFFMPEGInterfaceV107
// 2023/7/19: 添加IFFMPEGInterfaceV108和AV_INPUT_BUFFER_PADDING_SIZE
// 2023/8/24: 新增AV_HWDEVICE_TYPE_AMF
// 2024/6/12: 支持spadas9。支持FFMPEG6。增加AV_PIX_FMT_VULKAN
// 2024/10/16: 添加IFFMPEGInterfaceV110
// 2024/10/16: 补上AV_CODEC_ID_RAWVIDEO
// 2024/11/11: 添加IFFMPEGInterfaceV111
// 2024/12/31: 添加IFFMPEGInterfaceV112

#ifndef FFMPEGDL_H
#define FFMPEGDL_H 

#include "spadas.h"

#define FFMPEGDL_VER_MAJOR 1
#define FFMPEGDL_VER_MINOR 12

namespace spadas
{
    void getFFMPEGInterfaceVersion(UInt& major, UInt& minor);
    UInt getFFMPEGLibraryVersion();

    const Int SWS_BILINEAR = 2;
    const Int SWS_BICUBIC = 4;
    const Int SWS_POINT = 0x10;

    const Int AV_LOG_VERBOSE = 40;
    const Int AV_LOG_QUIET = -8;

    const Int AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX = 0x01;
    const Int AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX = 0x02;

    const Int AVSEEK_FLAG_BACKWARD = 1;
    const Int AVSEEK_FLAG_ANY = 4;

    const Int AVIO_FLAG_READ = 1;
    const Int AVIO_FLAG_WRITE = 2;

    const Int AV_PKT_FLAG_KEY = 0x0001;

    const Int AVFMT_GLOBALHEADER = 0x0040;

    const Int AV_CODEC_FLAG_GLOBAL_HEADER = (1 << 22);

    const Int AV_INPUT_BUFFER_PADDING_SIZE = 64;

    enum class AVPixelFormat
    {
        AV_PIX_FMT_NONE = 0,
        AV_PIX_FMT_OTHERS = 1,
        AV_PIX_FMT_YUV420P = 2,
        AV_PIX_FMT_NV12 = 3,
        AV_PIX_FMT_YUVJ420P = 4,
        AV_PIX_FMT_BGR24 = 5,
        AV_PIX_FMT_QSV = 6,
        AV_PIX_FMT_CUDA = 7,
        AV_PIX_FMT_DXVA2_VLD = 8,
        AV_PIX_FMT_D3D11 = 9,
        AV_PIX_FMT_VAAPI = 10,
        AV_PIX_FMT_VDPAU = 11,
        AV_PIX_FMT_VIDEOTOOLBOX = 12,
        AV_PIX_FMT_OPENCL = 13,
        AV_PIX_FMT_YUV422P = 14,
        AV_PIX_FMT_YUVJ422P = 15,
        AV_PIX_FMT_VULKAN = 16,
    };

    enum class AVErrorCode
    {
        AVERROR_NONE = 0,
        AVERROR_OTHERS = 1,
        AVERROR_EAGAIN = 2,
        AVERROR_EOF = 3,
    };

    enum class AVHWDeviceType
    {
        AV_HWDEVICE_TYPE_NONE = 0,
        AV_HWDEVICE_TYPE_OTHERS = 1,
        AV_HWDEVICE_TYPE_VDPAU = 2,
        AV_HWDEVICE_TYPE_CUDA = 3,
        AV_HWDEVICE_TYPE_VAAPI = 4,
        AV_HWDEVICE_TYPE_DXVA2 = 5,
        AV_HWDEVICE_TYPE_QSV = 6,
        AV_HWDEVICE_TYPE_VIDEOTOOLBOX = 7,
        AV_HWDEVICE_TYPE_D3D11VA = 8,
        AV_HWDEVICE_TYPE_AMF = 9,
    };

    enum class AVMediaType
    {
        AVMEDIA_TYPE_NONE = 0,
        AVMEDIA_TYPE_OTHERS = 1,
        AVMEDIA_TYPE_VIDEO = 2,
    };

    enum class AVCodecID
    {
        AV_CODEC_ID_NONE = 0,
        AV_CODEC_ID_OTHERS = 1,
        AV_CODEC_ID_MJPEG = 2,
        AV_CODEC_ID_H264 = 3,
        AV_CODEC_ID_H265 = 4,
        AV_CODEC_ID_YUV4 = 5,
        AV_CODEC_ID_Y41P = 6,
        AV_CODEC_ID_RAWVIDEO = 7,
    };

    typedef AVPixelFormat (*AVGetFormat)(Pointer ctx, Array<AVPixelFormat> formats);

    Int av_get_error_code_value(AVErrorCode code);
    void av_frame_free(Pointer framePtr);
    Pointer av_frame_alloc();
    void av_frame_set_format(Pointer frame, AVPixelFormat format);
    void av_frame_set_width(Pointer frame, Int width);
    void av_frame_set_height(Pointer frame, Int height);
    Int av_frame_get_buffer(Pointer frame, Int align);
    AVPixelFormat av_frame_get_format(Pointer frame);
    Int av_frame_get_width(Pointer frame);
    Int av_frame_get_height(Pointer frame);
    Int* av_frame_get_linesize(Pointer frame);
    Byte** av_frame_get_data(Pointer frame);
    Pointer avcodec_find_encoder_by_name(const Char *name);
    Pointer avcodec_alloc_context3(Pointer codec);
    void avcodec_set_bit_rate(Pointer ctx, Long bitRate);
    void avcodec_set_width(Pointer ctx, Int width);
    void avcodec_set_height(Pointer ctx, Int height);
    void avcodec_set_time_base(Pointer ctx, Int num, Int den);
    void avcodec_set_framerate(Pointer ctx, Int num, Int den);
    void avcodec_set_pix_fmt(Pointer ctx, AVPixelFormat format);
    void avcodec_set_qmin(Pointer ctx, Int qmin);
    void avcodec_set_qmax(Pointer ctx, Int qmax);
    Int avcodec_open2(Pointer ctx, Pointer codec, Pointer optionsPtr);
    AVPixelFormat avcodec_get_pix_fmt(Pointer ctx);
    Int avcodec_get_width(Pointer ctx);
    Int avcodec_get_height(Pointer ctx);
    Pointer sws_getContext(Int srcW, Int srcH, AVPixelFormat srcFormat, Int dstW, Int dstH, AVPixelFormat dstFormat, Int flags, Pointer srcFilter, Pointer dstFilter, Pointer param);
    Pointer av_packet_alloc();
    void avcodec_free_context(Pointer ctxPtr);
    void av_packet_free(Pointer packetPtr);
    void sws_freeContext(Pointer ctx);
    Int sws_scale(Pointer ctx, Byte **srcSlice, Int *srcStride, Int srcSliceY, Int srcSliceH, Byte **dst, Int *dstStride);
    Int avcodec_send_frame(Pointer ctx, Pointer frame);
    Int avcodec_receive_packet(Pointer ctx, Pointer packet);
    Int av_packet_get_size(Pointer packet);
    Byte* av_packet_get_data(Pointer packet);
    void av_packet_unref(Pointer packet);
    void av_log_set_level(Int level);
    Pointer avcodec_find_decoder_by_name(const Char *name);
    Int av_new_packet(Pointer packet, Int size);
    void av_packet_set_pts(Pointer packet, Long pts);
    void av_packet_set_dts(Pointer packet, Long dts);
    Int avcodec_send_packet(Pointer ctx, Pointer packet);
    Int avcodec_receive_frame(Pointer ctx, Pointer frame);
    Pointer avcodec_get_hw_config(Pointer codec, Int index);
    Int avcodec_hw_config_get_methods(Pointer hwConfig);
    AVHWDeviceType avcodec_hw_config_get_device_type(Pointer hwConfig);
    Int av_hwdevice_ctx_create(Pointer hwctxPtr, AVHWDeviceType type, const Char *device, Pointer options, Int flags);
    Pointer av_buffer_ref(Pointer buf);
    void av_buffer_unref(Pointer bufPtr);
    void avcodec_set_hw_device_ctx(Pointer ctx, Pointer hwctx);
    Int av_opt_set(Pointer obj, const Char *name, const Char *val, Int searchFlags);
    void avcodec_set_gop_size(Pointer ctx, Int gopSize);
    void avcodec_set_max_b_frames(Pointer ctx, Int maxBFrames);
    Pointer avcodec_get_priv_data(Pointer ctx);
    void av_frame_set_pts(Pointer frame, Long pts);
    Int avformat_open_input(Pointer fmtctxPtr, const Char *url, Pointer fmt, Pointer optionsPtr);
    Int avformat_find_stream_info(Pointer fmtctx, Pointer optionsPtr);
    void avformat_free_context(Pointer fmtctx);
    UInt avformat_get_nb_streams(Pointer fmtctx);
    Pointer *avformat_get_streams(Pointer fmtctx);
    AVMediaType avformat_stream_get_codec_type(Pointer stream);
    AVCodecID avformat_stream_get_codec_id(Pointer stream);
    Int avformat_stream_get_width(Pointer stream);
    Int avformat_stream_get_height(Pointer stream);
    void avformat_stream_get_time_base(Pointer stream, Int& num, Int& den);
    void avformat_close_input(Pointer fmtctxPtr);
    Int av_seek_frame(Pointer fmtctx, Int streamIndex, Long timestamp, Int flags);
    Int av_read_frame(Pointer fmtctx, Pointer packet);
    Int av_packet_get_stream_index(Pointer packet);
    Long av_packet_get_dts(Pointer packet);
    Int avformat_alloc_output_context2(Pointer fmtctxPtr, Pointer oformat, const Char *formatName, const Char *filename);
    Pointer avformat_new_stream(Pointer fmtctx, Pointer c);
    void avformat_stream_set_codec_type(Pointer stream, AVMediaType type);
    void avformat_stream_set_codec_id(Pointer stream, AVCodecID id);
    void avformat_stream_set_bit_rate(Pointer stream, Long rate);
    void avformat_stream_set_width(Pointer stream, Int width);
    void avformat_stream_set_height(Pointer stream, Int height);
    void avformat_stream_set_time_base(Pointer stream, Int num, Int den);
    void avformat_stream_set_codec_tag(Pointer stream, UInt tag);
    Pointer avformat_get_pb_ptr(Pointer fmtctx);
    Int avio_open(Pointer ioctxPtr, const Char *url, Int flags);
    Int avformat_write_header(Pointer fmtctx, Pointer optionsPtr);
    Pointer avformat_get_pb(Pointer fmtctx);
    Int avio_close(Pointer ioctx);
    void av_init_packet(Pointer packet);
    void av_packet_set_size(Pointer packet, Int size);
    void av_packet_set_data(Pointer packet, Byte *data);
    void av_packet_set_flags(Pointer packet, Int flags);
    Int av_packet_get_flags(Pointer packet);
    Int av_interleaved_write_frame(Pointer fmtctx, Pointer packet);
    Int av_write_frame(Pointer fmtctx, Pointer packet);
    Int av_write_trailer(Pointer fmtctx);
    void av_register_all();
    void avcodec_register_all();
    void av_free_packet(Pointer packet);
    Pointer av_mallocz_av_packet();
    Int avcodec_encode_video2(Pointer ctx, Pointer packet, Pointer frame, Int *gotPacketPtr);
    Pointer avformat_stream_get_codec(Pointer stream);
    Pointer avcodec_find_encoder(AVCodecID id);
    void avcodec_set_codec_tag(Pointer ctx, UInt tag);
    Int avformat_get_oformat_flags(Pointer fmtctx);
    Int avcodec_get_flags(Pointer ctx);
    void avcodec_set_flags(Pointer ctx, Int flags);
    AVCodecID avcodec_get_codec_id(Pointer ctx);
    AVMediaType avcodec_get_codec_type(Pointer ctx);
    Int avcodec_decode_video2(Pointer ctx, Pointer frame, Int *gotPicturePtr, Pointer packet);
    void avcodec_set_get_format(Pointer ctx, AVGetFormat getFormat);
    Int av_hwframe_transfer_data(Pointer dst, Pointer src, Int flags);
    void avcodec_set_opaque(Pointer ctx, Pointer userData);
    Pointer avcodec_get_opaque(Pointer ctx);
    Int av_dict_set(Pointer optionsPtr, const Char *key, const Char *value, Int flags);
    Pointer av_hwframe_ctx_alloc(Pointer hwctx);
    Pointer av_hwframe_ctx_get_data(Pointer hwframeCtx);
    AVPixelFormat avcodec_get_sw_pix_fmt(Pointer ctx);
    void av_hwframe_ctx_data_set_format(Pointer hwframeCtxData, AVPixelFormat format);
    void av_hwframe_ctx_data_set_sw_format(Pointer hwframeCtxData, AVPixelFormat swFormat);
    void av_hwframe_ctx_data_set_width_align32(Pointer hwframeCtxData, Int width);
    void av_hwframe_ctx_data_set_height_align32(Pointer hwframeCtxData, Int height);
    void av_hwframe_ctx_data_set_initial_pool_size(Pointer hwframeCtxData, Int size);
    Pointer av_hwframe_ctx_data_get_hwctx(Pointer hwframeCtxData);
    Int av_hwframe_ctx_init(Pointer hwframeCtx);
    void avcodec_set_hw_frames_ctx(Pointer ctx, Pointer hwframeCtx);
    Pointer av_frame_get_hw_frames_ctx(Pointer frame);
    Pointer avfilter_graph_alloc();
    const Pointer avfilter_get_by_name(const Char *name);
    Int avfilter_graph_create_filter(Pointer filtCtxPtr, const Pointer filt, const Char *name, const Char *args, Pointer opaque, Pointer graph_ctx);
    Int avfilter_link(Pointer srcFiltCtx, UInt srcpad, Pointer dstFiltCtx, UInt dstpad);
    void avfilter_ctx_set_input_hw_frames_ctx(Pointer filtCtx, UInt pad, Pointer hwframeCtx);
    Int avfilter_graph_config(Pointer graphCtx, Pointer logCtx);
    void avfilter_free(Pointer filtCtx);
    void avfilter_graph_free(Pointer graphCtxPtr);
    Int av_buffersrc_add_frame(Pointer filtCtx, Pointer frame);
    Int av_buffersink_get_frame(Pointer filtCtx, Pointer frame);
    Pointer av_malloc(ULong size);
    void avformat_stream_set_extradata(Pointer stream, Pointer extradata);
    void avformat_stream_set_extradata_size(Pointer stream, UInt size);
    void avcodec_set_extradata(Pointer ctx, Pointer extradata);
    void avcodec_set_extradata_size(Pointer ctx, UInt size);
    void avdevice_register_all();
    Int avformat_network_init();
    Int avformat_network_deinit();
    Pointer avformat_alloc_context();
    Pointer av_find_input_format(const Char *shortName);
    Pointer avformat_stream_get_codecpar(Pointer stream);
    Pointer avcodec_find_decoder(AVCodecID id);
    Int avcodec_parameters_to_context(Pointer ctx, const Pointer par);
    Int av_hwframe_get_buffer(Pointer hwframeCtx, Pointer frame, Int flags);
    Int avdevice_list_input_sources(Pointer device, const Char *deviceName, Pointer deviceOptions, Pointer deviceInfoListPtr);
    Int avdevice_list_get_nb_devices(Pointer deviceInfoList);
    Pointer *avdevice_list_get_devices(Pointer deviceInfoList);
    const Char *avdevice_get_device_name(Pointer deviceInfo);
    const Char *avdevice_get_device_description(Pointer deviceInfo);
    void avdevice_free_list_devices(Pointer deviceInfoListPtr);

    class IFFMPEGInterfaceV100
    {
    public:
        virtual ~IFFMPEGInterfaceV100() {}
        virtual Int av_get_error_code_value(AVErrorCode code);
        virtual void av_frame_free(Pointer framePtr);
        virtual Pointer av_frame_alloc();
        virtual void av_frame_set_format(Pointer frame, AVPixelFormat format);
        virtual void av_frame_set_width(Pointer frame, Int width);
        virtual void av_frame_set_height(Pointer frame, Int height);
        virtual Int av_frame_get_buffer(Pointer frame, Int align);
        virtual AVPixelFormat av_frame_get_format(Pointer frame);
        virtual Int av_frame_get_width(Pointer frame);
        virtual Int av_frame_get_height(Pointer frame);
        virtual Int* av_frame_get_linesize(Pointer fram);
        virtual Byte** av_frame_get_data(Pointer frame);
        virtual Pointer avcodec_find_encoder_by_name(const Char *name);
        virtual Pointer avcodec_alloc_context3(Pointer codec);
        virtual void avcodec_set_bit_rate(Pointer ctx, Long bitRate);
        virtual void avcodec_set_width(Pointer ctx, Int width);
        virtual void avcodec_set_height(Pointer ctx, Int height);
        virtual void avcodec_set_time_base(Pointer ctx, Int num, Int den);
        virtual void avcodec_set_framerate(Pointer ctx, Int num, Int den);
        virtual void avcodec_set_pix_fmt(Pointer ctx, AVPixelFormat format);
        virtual void avcodec_set_qmin(Pointer ctx, Int qmin);
        virtual void avcodec_set_qmax(Pointer ctx, Int qmax);
        virtual Int avcodec_open2(Pointer ctx, Pointer codec, Pointer optionsPtr);
        virtual AVPixelFormat avcodec_get_pix_fmt(Pointer ctx);
        virtual Int avcodec_get_width(Pointer ctx);
        virtual Int avcodec_get_height(Pointer ctx);
        virtual Pointer sws_getContext(Int srcW, Int srcH, AVPixelFormat srcFormat, Int dstW, Int dstH, AVPixelFormat dstFormat, Int flags, Pointer srcFilter, Pointer dstFilter, Pointer param);
        virtual Pointer av_packet_alloc();
        virtual void avcodec_free_context(Pointer ctxPtr);
        virtual void av_packet_free(Pointer packetPtr);
        virtual void sws_freeContext(Pointer ctx);
        virtual Int sws_scale(Pointer ctx, Byte **srcSlice, Int *srcStride, Int srcSliceY, Int srcSliceH, Byte **dst, Int *dstStride);
        virtual Int avcodec_send_frame(Pointer ctx, Pointer frame);
        virtual Int avcodec_receive_packet(Pointer ctx, Pointer packet);
        virtual Int av_packet_get_size(Pointer packet);
        virtual Byte* av_packet_get_data(Pointer packet);
        virtual void av_packet_unref(Pointer packet);
        virtual void av_log_set_level(Int level);
        virtual Pointer avcodec_find_decoder_by_name(const Char *name);
        virtual Int av_new_packet(Pointer packet, Int size);
        virtual void av_packet_set_pts(Pointer packet, Long pts);
        virtual void av_packet_set_dts(Pointer packet, Long dts);
        virtual Int avcodec_send_packet(Pointer ctx, Pointer packet);
        virtual Int avcodec_receive_frame(Pointer ctx, Pointer frame);
        virtual Pointer avcodec_get_hw_config(Pointer codec, Int index);
        virtual Int avcodec_hw_config_get_methods(Pointer hwConfig);
        virtual AVHWDeviceType avcodec_hw_config_get_device_type(Pointer hwConfig);
        virtual Int av_hwdevice_ctx_create(Pointer hwctxPtr, AVHWDeviceType type, const Char *device, Pointer options, Int flags);
        virtual Pointer av_buffer_ref(Pointer buf);
        virtual void av_buffer_unref(Pointer bufPtr);
        virtual void avcodec_set_hw_device_ctx(Pointer ctx, Pointer hwctx);
        virtual Int av_opt_set(Pointer obj, const Char *name, const Char *val, Int searchFlags);
        virtual void avcodec_set_gop_size(Pointer ctx, Int gopSize);
        virtual void avcodec_set_max_b_frames(Pointer ctx, Int maxBFrames);
        virtual Pointer avcodec_get_priv_data(Pointer ctx);
        virtual void av_frame_set_pts(Pointer frame, Long pts);
        virtual Int avformat_open_input(Pointer fmtctxPtr, const Char *url, Pointer fmt, Pointer optionsPtr);
        virtual Int avformat_find_stream_info(Pointer fmtctx, Pointer optionsPtr);
        virtual void avformat_free_context(Pointer fmtctx);
        virtual UInt avformat_get_nb_streams(Pointer fmtctx);
        virtual Pointer *avformat_get_streams(Pointer fmtctx);
        virtual AVMediaType avformat_stream_get_codec_type(Pointer stream);
        virtual AVCodecID avformat_stream_get_codec_id(Pointer stream);
        virtual Int avformat_stream_get_width(Pointer stream);
        virtual Int avformat_stream_get_height(Pointer stream);
        virtual void avformat_stream_get_time_base(Pointer stream, Int& num, Int& den);
        virtual void avformat_close_input(Pointer fmtctxPtr);
        virtual Int av_seek_frame(Pointer fmtctx, Int streamIndex, Long timestamp, Int flags);
        virtual Int av_read_frame(Pointer fmtctx, Pointer packet);
        virtual Int av_packet_get_stream_index(Pointer packet);
        virtual Long av_packet_get_dts(Pointer packet);
        virtual Int avformat_alloc_output_context2(Pointer fmtctxPtr, Pointer oformat, const Char *formatName, const Char *filename);
        virtual Pointer avformat_new_stream(Pointer fmtctx, Pointer c);
        virtual void avformat_stream_set_codec_type(Pointer stream, AVMediaType type);
        virtual void avformat_stream_set_codec_id(Pointer stream, AVCodecID id);
        virtual void avformat_stream_set_bit_rate(Pointer stream, Long rate);
        virtual void avformat_stream_set_width(Pointer stream, Int width);
        virtual void avformat_stream_set_height(Pointer stream, Int height);
        virtual void avformat_stream_set_time_base(Pointer stream, Int num, Int den);
        virtual void avformat_stream_set_codec_tag(Pointer stream, UInt tag);
        virtual Pointer avformat_get_pb_ptr(Pointer fmtctx);
        virtual Int avio_open(Pointer ioctxPtr, const Char *url, Int flags);
        virtual Int avformat_write_header(Pointer fmtctx, Pointer optionsPtr);
        virtual Pointer avformat_get_pb(Pointer fmtctx);
        virtual Int avio_close(Pointer ioctx);
        virtual void av_init_packet(Pointer packet);
        virtual void av_packet_set_size(Pointer packet, Int size);
        virtual void av_packet_set_data(Pointer packet, Byte *data);
        virtual void av_packet_set_flags(Pointer packet, Int flags);
        virtual Int av_packet_get_flags(Pointer packet);
        virtual Int av_interleaved_write_frame(Pointer fmtctx, Pointer packet);
        virtual Int av_write_frame(Pointer fmtctx, Pointer packet);
        virtual Int av_write_trailer(Pointer fmtctx);
    };

    class IFFMPEGInterfaceV101
    {
    public:
        virtual ~IFFMPEGInterfaceV101() {}
        virtual void av_register_all();
        virtual void avcodec_register_all();
    };

    class IFFMPEGInterfaceV102
    {
    public:
        virtual ~IFFMPEGInterfaceV102() {}
        virtual void av_free_packet(Pointer packet);
        virtual Pointer av_mallocz_av_packet();
        virtual Int avcodec_encode_video2(Pointer ctx, Pointer packet, Pointer frame, Int *gotPacketPtr);
        virtual Pointer avformat_stream_get_codec(Pointer stream);
        virtual Pointer avcodec_find_encoder(AVCodecID id);
        virtual void avcodec_set_codec_tag(Pointer ctx, UInt tag);
        virtual Int avformat_get_oformat_flags(Pointer fmtctx);
        virtual Int avcodec_get_flags(Pointer ctx);
        virtual void avcodec_set_flags(Pointer ctx, Int flags);
        virtual AVCodecID avcodec_get_codec_id(Pointer ctx);
        virtual AVMediaType avcodec_get_codec_type(Pointer ctx);
        virtual Int avcodec_decode_video2(Pointer ctx, Pointer frame, Int *gotPicturePtr, Pointer packet);
    };

    class IFFMPEGInterfaceV103
    {
    public:
        virtual ~IFFMPEGInterfaceV103() {}
        virtual void avcodec_set_get_format(Pointer ctx, AVGetFormat getFormat);
    };

    class IFFMPEGInterfaceV104
    {
    public:
        virtual ~IFFMPEGInterfaceV104() {}
        virtual Int av_hwframe_transfer_data(Pointer dst, Pointer src, Int flags);
        virtual void avcodec_set_opaque(Pointer ctx, Pointer userData);
        virtual Pointer avcodec_get_opaque(Pointer ctx);
    };

    class IFFMPEGInterfaceV105
    {
    public:
        virtual ~IFFMPEGInterfaceV105() {}
        virtual Int av_dict_set(Pointer optionsPtr, const Char *key, const Char *value, Int flags);
    };

    class IFFMPEGInterfaceV107
    {
    public:
        virtual ~IFFMPEGInterfaceV107() {}
        virtual Pointer av_hwframe_ctx_alloc(Pointer hwctx);
        virtual Pointer av_hwframe_ctx_get_data(Pointer hwframeCtx);
        virtual AVPixelFormat avcodec_get_sw_pix_fmt(Pointer ctx);
        virtual void av_hwframe_ctx_data_set_format(Pointer hwframeCtxData, AVPixelFormat format);
        virtual void av_hwframe_ctx_data_set_sw_format(Pointer hwframeCtxData, AVPixelFormat swFormat);
        virtual void av_hwframe_ctx_data_set_width_align32(Pointer hwframeCtxData, Int width);
        virtual void av_hwframe_ctx_data_set_height_align32(Pointer hwframeCtxData, Int height);
        virtual void av_hwframe_ctx_data_set_initial_pool_size(Pointer hwframeCtxData, Int size);
        virtual Pointer av_hwframe_ctx_data_get_hwctx(Pointer hwframeCtxData);
        virtual Int av_hwframe_ctx_init(Pointer hwframeCtx);
        virtual void avcodec_set_hw_frames_ctx(Pointer ctx, Pointer hwframeCtx);
        virtual Pointer av_frame_get_hw_frames_ctx(Pointer frame);
        virtual Pointer avfilter_graph_alloc();
        virtual const Pointer avfilter_get_by_name(const Char *name);
        virtual Int avfilter_graph_create_filter(Pointer filtCtxPtr, const Pointer filt, const Char *name, const Char *args, Pointer opaque, Pointer graphCtx);
        virtual Int avfilter_link(Pointer srcFiltCtx, UInt srcpad, Pointer dstFiltCtx, UInt dstpad);
        virtual void avfilter_ctx_set_input_hw_frames_ctx(Pointer filtCtx, UInt pad, Pointer hwframeCtx);
        virtual Int avfilter_graph_config(Pointer graphCtx, Pointer logCtx);
        virtual void avfilter_free(Pointer filtCtx);
        virtual void avfilter_graph_free(Pointer graphCtxPtr);
        virtual Int av_buffersrc_add_frame(Pointer filtCtx, Pointer frame);
        virtual Int av_buffersink_get_frame(Pointer filtCtx, Pointer frame);
    };

    class IFFMPEGInterfaceV108
    {
    public:
        virtual ~IFFMPEGInterfaceV108() {}
        virtual Pointer av_malloc(ULong size);
        virtual void avformat_stream_set_extradata(Pointer stream, Pointer extradata);
        virtual void avformat_stream_set_extradata_size(Pointer stream, UInt size);
        virtual void avcodec_set_extradata(Pointer ctx, Pointer extradata);
        virtual void avcodec_set_extradata_size(Pointer ctx, UInt size);
    };

    class IFFMPEGInterfaceV110
    {
    public:
        virtual ~IFFMPEGInterfaceV110() {}
        virtual void avdevice_register_all();
        virtual Int avformat_network_init();
        virtual Int avformat_network_deinit();
        virtual Pointer avformat_alloc_context();
        virtual Pointer av_find_input_format(const Char *shortName);
        virtual Pointer avformat_stream_get_codecpar(Pointer stream);
        virtual Pointer avcodec_find_decoder(AVCodecID id);
        virtual Int avcodec_parameters_to_context(Pointer ctx, const Pointer par);
    };

    class IFFMPEGInterfaceV111
    {
    public:
        virtual ~IFFMPEGInterfaceV111() {}
        virtual Int av_hwframe_get_buffer(Pointer hwframeCtx, Pointer frame, Int flags);
    };

    class IFFMPEGInterfaceV112
    {
    public:
        virtual ~IFFMPEGInterfaceV112() {}
        virtual Int avdevice_list_input_sources(Pointer device, const Char *deviceName, Pointer deviceOptions, Pointer deviceInfoListPtr);
        virtual Int avdevice_list_get_nb_devices(Pointer deviceInfoList);
        virtual Pointer *avdevice_list_get_devices(Pointer deviceInfoList);
        virtual const Char *avdevice_get_device_name(Pointer deviceInfo);
        virtual const Char *avdevice_get_device_description(Pointer deviceInfo);
        virtual void avdevice_free_list_devices(Pointer deviceInfoListPtr);
    };
}

#endif